/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;

namespace GrooveCommands
{
	class GrooveDir : CommandUtils.GrooveUtilBase
	{
		private string m_AccountURI = null;

		private const int OutputOption_Accounts = 0x1;
		private const int OutputOption_Identities = 0x2;
		private const int OutputOption_Contacts = 0x4;
		private const int OutputOption_Spaces = 0x8;
		private const int OutputOption_Tools = 0x10;
		private const int OutputOption_Members = 0x20;
		private const int OutputOption_VCards = 0x40;
		private const int OutputOption_GFS_Spaces = 0x80;
		private const int OutputOption_All = 0xFF;

		private const int ProcessOption_Accounts = 0x1;
		private const int ProcessOption_Identities = ProcessOption_Accounts + 0x2;
		private const int ProcessOption_Contacts = ProcessOption_Accounts + 0x4;
		private const int ProcessOption_Spaces = ProcessOption_Identities + 0x8;
		private const int ProcessOption_Tools = ProcessOption_Spaces + 0x10;
		private const int ProcessOption_Members = ProcessOption_Spaces + 0x20;
		// unused 0x40
		private const int ProcessOption_GFS_Spaces = ProcessOption_Spaces + 0x80;
		private const int ProcessOption_All = 0xFF;

		private int m_OutputOptions = 0;
		private int m_ProcessOptions = 0;
		private int m_StringPadCount = 1;

		private const string GROOVE_SPACE_TYPE_GFS = "urn:groove.net:Groove.Core.Tools.System.TelespaceTypes.GFS";

		[STAThread]
		static void Main(string[] i_Arguments)
		{
			CommandUtils.UtilAppMain.RunApplication(new GrooveDir(i_Arguments));
		}

		public GrooveDir(string[] i_Arguments)
			: base (i_Arguments, true)
		{
			base.UsageMessage = "GrooveDir [PARAMS...]";
			base.HelpMessage = 
				"GrooveDir\r\n\t" + 
				"Displays a list of Groove objects\r\n" +
				"Parameters:\r\n\t" +
				"[/a                  Groove Accounts]\r\n\t" +
				"[/i                  Groove Identities]\r\n\t" +
				"[/c                  Groove Contacts]\r\n\t" +
				"[/d                  Groove VCard details]\r\n\t" +
				"[/f                  Groove File Sharing Spaces]\r\n\t" +
				"[/s                  Groove Spaces]\r\n\t" +
				"[/t                  Groove Tools]\r\n\t" +
				"[/m                  Groove Members]\r\n\t" +
				"[/v                  Verbose output]\r\n\t" +
				"[/Account=           Only process the specified Account]\r\n\t" +
				"[/RequestKey=        Token used to communicate Groove host]\r\n\t" +
				"[/Host=              The remote Groove host name to issue commands to]\r\n\t" +
				"[/Timeout=           Timeout (in ms) for Web Services method execution]\r\n\t" +
				"[/X                  Configuration file to use for parameter input]\r\n\t" +
				"\r\n" +
				"NOTES:\r\n" +
				"The /d flag (contact details) implies /c (retrieve the list of contacts).\r\n" +
				"When /d /v (verbose details), the output includes full vCard for each contact.\r\n" +				
				"The /f flag (File Sharing Spaces) by itself displays Groove File Sharing (GFS) workspaces only.\r\n" +
				"The /s flag (Groove Spaces) displays Standard Groove workspaces only.\r\n" +
				"Specify both /f and /s to display information about both Standard and GFS workspaces.\r\n" +
				"The /t flag (Groove Tools) lists tools in Standard Groove workspaces only.\r\n" + 
				"GrooveDir does not display any information about tools in GFS workspaces.\r\n" +				
				"The /m flag (Groove Members) by itself displays membership of Standard Groove workspaces only.\r\n" +
				"Specify both /f and /m to display membership of both Standard and GFS workspaces. \r\n" +
				"\r\n";
		}

		public override CheckResult CheckParameters()
		{
			CommandUtils.UtilBase.CheckResult CheckResult = base.CheckParameters();
			if (CheckResult != CommandUtils.UtilBase.CheckResult.Succeeded )
				return CheckResult;
		
			m_AccountURI = base.GetParameterValue( "Account" );

			if (base.GetParameterValueFlag("a"))
			{
				m_ProcessOptions |= ProcessOption_Accounts;
				m_OutputOptions |= OutputOption_Accounts;
			}

			if (base.GetParameterValueFlag("i"))
			{
				m_ProcessOptions |= ProcessOption_Identities;
				m_OutputOptions |= OutputOption_Identities;
			}

			if (base.GetParameterValueFlag("c"))
			{
				m_ProcessOptions |= ProcessOption_Contacts;
				m_OutputOptions |= OutputOption_Contacts;
			}

			if (base.GetParameterValueFlag("d"))
			{
				m_ProcessOptions |= ProcessOption_Contacts;
				m_OutputOptions |= OutputOption_Contacts;
				m_OutputOptions |= OutputOption_VCards;
			}

			if (base.GetParameterValueFlag("f"))
			{
				m_ProcessOptions |= ProcessOption_GFS_Spaces;
				m_OutputOptions |= OutputOption_GFS_Spaces;
			}

			if (base.GetParameterValueFlag("s"))
			{
				m_ProcessOptions |= ProcessOption_Spaces;
				m_OutputOptions |= OutputOption_Spaces;
			}

			if (base.GetParameterValueFlag("t"))
			{
				m_ProcessOptions |= ProcessOption_Tools;
				m_OutputOptions |= OutputOption_Tools;
			}

			if (base.GetParameterValueFlag("m"))
			{
				m_ProcessOptions |= ProcessOption_Members;
				m_OutputOptions |= OutputOption_Members;
			}

			if (m_ProcessOptions == 0)
				m_ProcessOptions = ProcessOption_All;

			if (m_OutputOptions == 0)
				m_OutputOptions |= OutputOption_All;

			return base.CheckUnusedParameters();
		}

		public override CommandUtils.UtilBase.CheckResult Run()
		{
			base.StandardOutput.WriteLine("<GrooveDir>");

			GrooveWebServicesV12Helpers.Account[] Accounts = null;

			try
			{
				Accounts = GrooveWebServicesV12Helpers.Account.GetAccounts(base.Context);
			}
			catch (System.Exception Exception)
			{
				base.StandardError.WriteLine("Unable to get list of accounts: " + Exception.Message);
				throw Exception;
			}

			string AccountStringPad = new string(' ', 2*m_StringPadCount);

			bool OutputAccounts = 
				(Accounts.Length >	1) || 
				((m_OutputOptions & OutputOption_Accounts) == OutputOption_Accounts) || 
				(m_OutputOptions == OutputOption_All);

			foreach (GrooveWebServicesV12Helpers.Account Account in Accounts)
			{
				if (m_AccountURI!=null && m_AccountURI!=Account.URI)
				{
					// We have a specified account; this is not it
					continue;
				}
				if (OutputAccounts)
				{
					++m_StringPadCount;
					string AccountInfo = System.String.Format
						(
						"{0}<Account Name='{1}' URI='{2}' ",
						AccountStringPad,
						CommandUtils.UtilStatic.XMLEncode(Account.Name),
						Account.URI
						);

					if (base.Verbose)
					{
						string VerboseInfo = System.String.Format
							(
							"ContactsURI='{0}' MessagesURI='{1}'",
							Account.ContactsURI,
							Account.MessagesURI
							);

						AccountInfo += VerboseInfo;
					}

					AccountInfo += ">";

					base.StandardOutput.WriteLine(AccountInfo);
				}

				if ((m_ProcessOptions & ProcessOption_Identities) == ProcessOption_Identities)
				{
					GrooveWebServicesV12Helpers.Identity[] Identities = null;

					try
					{
						Identities = Account.Identities;
					}
					catch (System.Exception Exception)
					{
						base.StandardError.WriteLine("\nUnable to get list of identites: " + Exception.Message);
						throw Exception;
					}

					string IdentityStringPad = new string(' ', 2*m_StringPadCount);

					bool OutputIdentities = 
						(Identities.Length > 1) || 
						((m_OutputOptions & OutputOption_Identities) == OutputOption_Identities) || 
						(m_OutputOptions == OutputOption_All);

					foreach (GrooveWebServicesV12Helpers.Identity Identity in Identities)
					{
						if (OutputIdentities)
						{
							++m_StringPadCount;

							string IdentityInfo = System.String.Format
								(
								"{0}<Identity Name='{1}' URI='{2}' ",
								IdentityStringPad,
								CommandUtils.UtilStatic.XMLEncode(Identity.Name),
								Identity.URI
								);

							if (base.Verbose)
							{
								string VerboseInfo = System.String.Format
									(
									"SpacesURI='{0}'",
									Identity.SpacesURI
									);

								IdentityInfo += VerboseInfo;
							}

							IdentityInfo += ">";

							base.StandardOutput.WriteLine(IdentityInfo);
						}

						if ((m_ProcessOptions & ProcessOption_Spaces) == ProcessOption_Spaces)
						{
							GrooveWebServicesV12Helpers.Space[] Spaces = null;
							GrooveWebServicesV12Helpers.Space[] GFS_Spaces = null;

							bool OutputSpaces = false;
							bool OutputGFS_Spaces = false;

							try
							{
								Spaces = Identity.StandardSpaces;
							}
							catch (System.Exception Exception)
							{
								base.StandardError.WriteLine("Unable to get list of spaces: " + Exception.Message);
								throw Exception;
							}

							OutputSpaces = 
								//(Spaces.Length > 1) || 
								((m_OutputOptions & OutputOption_Spaces) == OutputOption_Spaces) || 
								(m_OutputOptions == OutputOption_All);

							if ((m_ProcessOptions & ProcessOption_GFS_Spaces) == ProcessOption_GFS_Spaces)
							{
								try
								{
									GFS_Spaces = Identity.GetSpaces(GROOVE_SPACE_TYPE_GFS);
								}
								catch (System.Exception Exception)
								{
									base.StandardError.WriteLine("Unable to get list of GFS Spaces: " + Exception.Message);
									throw Exception;
								}
								
								OutputGFS_Spaces = 
									//(GFS_Spaces.Length > 1) || 
									((m_OutputOptions & OutputOption_GFS_Spaces) == OutputOption_GFS_Spaces) ||
									(m_OutputOptions == OutputOption_All);
							}
							
							foreach (GrooveWebServicesV12Helpers.Space Space in Spaces)
							{
								if (OutputSpaces)
								{
									WriteSpaceElements(Space);
								}

								if (Space.IsLocal && ((m_ProcessOptions & ProcessOption_Tools) == ProcessOption_Tools))
								{
									WriteToolElements(Space);									
								}

								if (Space.IsLocal && ((m_ProcessOptions & ProcessOption_Members) == ProcessOption_Members))
								{
									WriteMemberElements(Space);									
								}

								if (OutputSpaces)
								{
									--m_StringPadCount;
									string SpaceStringPad = new string(' ', 2*m_StringPadCount);
									base.StandardOutput.WriteLine(SpaceStringPad + "</Space>");
								}
							}

							if (GFS_Spaces != null)
							{
								foreach (GrooveWebServicesV12Helpers.Space GFS_Space in GFS_Spaces)
								{
									if (OutputGFS_Spaces)
									{
										WriteSpaceElements(GFS_Space);

										// You cannot read the tools in a File Sharing Space and access any of the files 
										// in the workspace through Groove Web Services. 
										// If you could, you would include the following commented-out code:
										//if (GFS_Space.IsLocal && ((m_ProcessOptions & ProcessOption_Tools) == ProcessOption_Tools))
										//{
										//	 WriteToolElements(GFS_Space);									
										//}
										//
										// You can access the workspace members.
										if (GFS_Space.IsLocal && ((m_ProcessOptions & ProcessOption_Members) == ProcessOption_Members))
										{
											WriteMemberElements(GFS_Space);									
										}
									
										WriteEndSpaceElement();
									}
								}

							}
						} // ProcessOption_Spaces
						
						if (OutputIdentities)
						{
							--m_StringPadCount;
							base.StandardOutput.WriteLine(IdentityStringPad + "</Identity>");
						}
					}
				}

				bool OutputContacts = 
					((m_OutputOptions & OutputOption_Contacts) == OutputOption_Contacts) || 
					(m_OutputOptions == OutputOption_All);

				if (OutputContacts)
				{
					System.Collections.ArrayList ContactsArrayList = new System.Collections.ArrayList();

					try
					{
						ContactsArrayList.Add(Account.PersonalContacts);
					}
					catch (System.Exception Exception)
					{
						base.StandardError.WriteLine("\nUnable to get list of personal contacts: " + Exception.Message);
						throw Exception;
					}

					try
					{
						ContactsArrayList.Add(Account.SharedSpaceContacts);
					}
					catch (System.Exception Exception)
					{
						base.StandardError.WriteLine("\nUnable to get list of shared space contacts: " + Exception.Message);
						throw Exception;
					}

					try
					{
						//ContactsArrayList.Add(Account.UserContacts);
					}
					catch (System.Exception Exception)
					{
						base.StandardError.WriteLine("\nUnable to get list of user contacts: " + Exception.Message);
						throw Exception;
					}
					
					string ContactStringPad = new string(' ', 2*m_StringPadCount);

					bool OutputVCards = 
						((m_OutputOptions & OutputOption_VCards) == OutputOption_VCards) || 
						(m_OutputOptions == OutputOption_All);

					foreach (GrooveWebServicesV12Helpers.Contact[] Contacts in ContactsArrayList)
					{
						foreach (GrooveWebServicesV12Helpers.Contact Contact in Contacts)
						{
							string OutputVCardContent = "";
							string PreferredEmail = "";
							if (OutputVCards)
							{	
								++m_StringPadCount;
								string VCardStringPad = new string(' ', 2*m_StringPadCount);
								string VCardStringPad2 = new string(' ', 2*m_StringPadCount + 2);

								// VCard XML serialization format is defined by
								// http://www.jabber.org/jeps/jep-0054.html

								GrooveWebServicesV12Helpers.VCard VCard = Contact.VCard;
								OutputVCardContent = 
									VCardStringPad +
									"<vCard xmlns='vcard-temp'>";
								
								OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;

								OutputVCardContent += "<FN>" + CommandUtils.UtilStatic.XMLEncode(VCard.FullName) + "</FN>";
								if (VCard.NickName != "")
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<NICKNAME>" + CommandUtils.UtilStatic.XMLEncode(VCard.NickName) + "</NICKNAME>";
								}

								GrooveWebServicesV12Helpers.Name Name = VCard.Name;
								OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
								OutputVCardContent += "<N>";
								if (Name.Family != "")
									OutputVCardContent += "<FAMILY>" + CommandUtils.UtilStatic.XMLEncode(Name.Family) + "</FAMILY>";

								if (Name.Given != "")
									OutputVCardContent += "<GIVEN>" + CommandUtils.UtilStatic.XMLEncode(Name.Given) + "</GIVEN>";

								if (Name.Other != "")
									OutputVCardContent += "<MIDDLE>" + CommandUtils.UtilStatic.XMLEncode(Name.Other) + "</MIDDLE>";

								if (Name.Prefix != "")
									OutputVCardContent += "<PREFIX>" + CommandUtils.UtilStatic.XMLEncode(Name.Prefix) + "</PREFIX>";

								if (Name.Suffix != "")
									OutputVCardContent += "<SUFFIX>" + CommandUtils.UtilStatic.XMLEncode(Name.Suffix) + "</SUFFIX>";

								OutputVCardContent += "</N>";

								GrooveWebServicesV12Helpers.Organization Org = VCard.Organization;
								if (Org.Title != "")
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<TITLE>" + CommandUtils.UtilStatic.XMLEncode(Org.Title) + "</TITLE>";
								}

								if (Org.Role != "")
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<ROLE>" + CommandUtils.UtilStatic.XMLEncode(Org.Role) + "</ROLE>";
								}

								GrooveWebServicesV12Helpers.GrooveVCardWebService.OrganizationInfo[] OrgInfos = Org.OrganizationInfos;
								foreach (GrooveWebServicesV12Helpers.GrooveVCardWebService.OrganizationInfo OrgInfo in OrgInfos)
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<ORG>";
									OutputVCardContent += "<ORGNAME>" + CommandUtils.UtilStatic.XMLEncode(OrgInfo.Name) + "</ORGNAME>";
									OutputVCardContent += "<ORGUNIT>" + CommandUtils.UtilStatic.XMLEncode(OrgInfo.Unit) + "</ORGUNIT>";
									OutputVCardContent += "</ORG>";
								}

								foreach (GrooveWebServicesV12Helpers.Phone Phone in VCard.PhoneNumbers)
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<TEL>";
									foreach (GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType PhoneType in Phone.PhoneTypes)
									{
										switch (PhoneType)
										{
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.preferred:
											{
												OutputVCardContent += "<PREF/>";
												break;
											}

											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.message:
											{
												OutputVCardContent += "<MSG/>";
												break;
											}

											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.bbs:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.car:												OutputVCardContent += "<HOME/>"; break;
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.cell:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.fax:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.home:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.isdn:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.modem:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.pager:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.pcs:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.video:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.voice:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.PhoneType.work:
											default:
											{
												OutputVCardContent += "<" + PhoneType.ToString().ToUpper() + "/>";
												break;
											}
										}
									}
									OutputVCardContent += "<NUMBER>" + CommandUtils.UtilStatic.XMLEncode(Phone.PhoneNumber) + "</NUMBER>";
									OutputVCardContent += "</TEL>";
								}

								foreach (GrooveWebServicesV12Helpers.Address Address in VCard.Addresses)
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<ADR>";
									foreach (GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType DeliveryType in Address.DeliveryTypes)
									{
										switch (DeliveryType)
										{
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.domestic:
											{
												OutputVCardContent += "<DOM/>";
												break;
											}

											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.international:
											{
												OutputVCardContent += "<INTL/>";
												break;
											}

											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.home:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.parcel:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.postal:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.DeliveryType.work:
											default:
											{
												OutputVCardContent += "<" + DeliveryType.ToString().ToUpper() + "/>";
												break;
											}
										}
									}

									if (Address.PoBox != "")
										OutputVCardContent += "<POBOX>" + CommandUtils.UtilStatic.XMLEncode(Address.PoBox) + "</POBOX>";

									if (Address.Extended != "")
										OutputVCardContent += "<EXTADD>" + CommandUtils.UtilStatic.XMLEncode(Address.Extended) + "</EXTADD>";

									if (Address.Street != "")
										OutputVCardContent += "<STREET>" + CommandUtils.UtilStatic.XMLEncode(Address.Street) + "</STREET>";

									if (Address.Locality != "")
										OutputVCardContent += "<LOCALITY>" + CommandUtils.UtilStatic.XMLEncode(Address.Locality) + "</LOCALITY>";

									if (Address.Region != "")
										OutputVCardContent += "<REGION>" + CommandUtils.UtilStatic.XMLEncode(Address.Region) + "</REGION>";

									if (Address.PostCode != "")
										OutputVCardContent += "<PCODE>" + CommandUtils.UtilStatic.XMLEncode(Address.PostCode) + "</PCODE>";

									if (Address.Country != "")
										OutputVCardContent += "<CTRY>" + CommandUtils.UtilStatic.XMLEncode(Address.Country) + "</CTRY>";

									OutputVCardContent += "</ADR>";
								}

								foreach (GrooveWebServicesV12Helpers.Email Email in VCard.EmailAddresses)
								{
									OutputVCardContent += base.StandardOutput.NewLine + VCardStringPad2;
									OutputVCardContent += "<EMAIL>";
									foreach (GrooveWebServicesV12Helpers.GrooveVCardWebService.EmailType EmailType in Email.EmailTypes)
									{
										switch (EmailType)
										{
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.EmailType.preferred:
											{
												PreferredEmail = Email.EmailAddress;
												OutputVCardContent += "<PREF/>";
												break;
											}

											case GrooveWebServicesV12Helpers.GrooveVCardWebService.EmailType.internet:
											case GrooveWebServicesV12Helpers.GrooveVCardWebService.EmailType.x400:
											default:
											{
												OutputVCardContent += "<" + EmailType.ToString().ToUpper() + "/>";
												break;
											}
										}
									}

									OutputVCardContent += "<USERID>" + CommandUtils.UtilStatic.XMLEncode(Email.EmailAddress) + "</USERID>";
									OutputVCardContent += "</EMAIL>";
								}

								OutputVCardContent += VCardStringPad + "</vCard>";
								--m_StringPadCount;

								// Finally, if not verbose, throw it all away (we only wanted PreferredEmail)
								if (!base.Verbose)
									OutputVCardContent = "";
							}

							string OutputContactContent = 
								ContactStringPad + 
								"<" +
								"Contact Name='" + CommandUtils.UtilStatic.XMLEncode(Contact.Name) + "'" +
								" URI='" + Contact.URI + "'";

							if ((PreferredEmail != "") || base.Verbose)
								OutputContactContent += " PreferredEmail='" + CommandUtils.UtilStatic.XMLEncode( PreferredEmail ) + "'";

							if (base.Verbose)
							{
								OutputContactContent +=
									" Awareness='" + Contact.Awareness + "'" +
									" TimeWentIdle='" + Contact.TimeWentIdle + "'" +
									" Type='" + Contact.Type + "'" +
									" VCardURI='" + Contact.VCardURI + "'";
							}

							if (OutputVCardContent == "")
							{
								OutputContactContent +=	"/>";
								base.StandardOutput.WriteLine(OutputContactContent);
							}
							else
							{
								OutputContactContent +=	">";
								base.StandardOutput.WriteLine(OutputContactContent);
								base.StandardOutput.WriteLine(OutputVCardContent);
								base.StandardOutput.WriteLine(ContactStringPad + "</Contact>");
							}
						}
					}
				}

				if (OutputAccounts)
				{
					--m_StringPadCount;
					base.StandardOutput.WriteLine(AccountStringPad + "</Account>");
				}
			}

			base.StandardOutput.WriteLine("</GrooveDir>");

			return CommandUtils.UtilBase.CheckResult.Succeeded;
		}

	
		private void WriteSpaceElements(GrooveWebServicesV12Helpers.Space i_Space)
		{
			string SpaceStringPad = new string(' ', 2*m_StringPadCount);

			string OutputSpaceContent = 
				SpaceStringPad + 
				"<" +
				"Space Name='" + CommandUtils.UtilStatic.XMLEncode(i_Space.Name) + "'" +
				" URI='" + i_Space.URI + "'";
									
			if (base.Verbose)
			{
				OutputSpaceContent +=
					" Created='" + i_Space.Created + "'" +
					" Description='" + CommandUtils.UtilStatic.XMLEncode(i_Space.Description) + "'" +
					" IsLocal='" + i_Space.IsLocal + "'" +
					" LocalURI='" + i_Space.LocalURI + "'" +
					" Modified='" + i_Space.Modified + "'" +
					" Type='" + i_Space.Type + "'" +
					" Unread='" + i_Space.IsUnread + "'" +
					" ToolsURI='" + i_Space.ToolsURI + "'" +
					" MembersURI='" + i_Space.MembersURI + "'";
											
				if (i_Space.IsLocal)
					OutputSpaceContent += " Version='" + i_Space.Version.Major + "," + i_Space.Version.Minor + "," + i_Space.Version.Custom + "," + i_Space.Version.Sequence + "'";
			}
										
			OutputSpaceContent += ">";

			++m_StringPadCount;
			base.StandardOutput.WriteLine(OutputSpaceContent);
		}
	
		private void WriteToolElements(GrooveWebServicesV12Helpers.Space i_Space)
		{
			// You cannot read the tools nor access any of the files in a GFS workspace 
			// through Groove Web Services.
			if (i_Space.Type == GROOVE_SPACE_TYPE_GFS)
			{
				return;
			}

			GrooveWebServicesV12Helpers.Tool[] Tools = null;

			try
			{
				Tools = i_Space.Tools;
			}
			catch (System.Exception Exception)
			{
				base.StandardError.WriteLine("Unable to get list of tools: " + Exception.Message);
				throw Exception;
			}

			string ToolStringPad = new string(' ', 2*m_StringPadCount);

			bool OutputTools = 
				((m_OutputOptions & OutputOption_Tools) == OutputOption_Tools) || 
				(m_OutputOptions == OutputOption_All);

			foreach (GrooveWebServicesV12Helpers.Tool Tool in Tools)
			{
				if (OutputTools)
				{
					string OutputToolContent = 
						ToolStringPad + 
						"<" +
						"Tool Name='" + CommandUtils.UtilStatic.XMLEncode(Tool.Name) + "'" +
						" URI='" + Tool.URI + "'";

					if (base.Verbose)
					{
						string FixedUpComponentResourceURL = Tool.ComponentResourceURL.Replace("&", "&amp;");

						OutputToolContent +=
							" Category='" + CommandUtils.UtilStatic.XMLEncode(Tool.Category) + "'" +
							" ComponentResourceURL='" + CommandUtils.UtilStatic.XMLEncode(Tool.ComponentResourceURL) + "'" +
							" Creator='" + Tool.Creator + "'" +
							" ID='" + Tool.ID + "'" +
							" LocalURI='" + Tool.LocalURI + "'" +
							" Owner='" + Tool.Owner + "'" +
							" Type='" + Tool.Type + "'" +
							" Unread='" + Tool.IsUnread + "'" +
							" MembersURI='" + Tool.MembersURI + "'" +
							" Data='" + Tool.Data + "'";
					}
													
					OutputToolContent += "/>";

					base.StandardOutput.WriteLine(OutputToolContent);
				}
			}
		}

		private void WriteMemberElements(GrooveWebServicesV12Helpers.Space i_Space)
		{
			GrooveWebServicesV12Helpers.Member[] Members = null;

			try
			{
				Members = i_Space.Members;
			}
			catch (System.Exception Exception)
			{
				base.StandardError.WriteLine("Unable to get list of members: " + Exception.Message);
				throw Exception;
			}

			string MemberStringPad = new string(' ', 2*m_StringPadCount);

			bool OutputMembers = 
				((m_OutputOptions & OutputOption_Members) == OutputOption_Members) || 
				(m_OutputOptions == OutputOption_All);

			foreach (GrooveWebServicesV12Helpers.Member Member in Members)
			{
				if (OutputMembers)
				{
					string OutputMemberContent = 
						MemberStringPad + 
						"<" +
						"Member Name='" + CommandUtils.UtilStatic.XMLEncode(Member.Name) + "'" +
						" URI='" + Member.URI + "'";

					if (base.Verbose)
					{
						OutputMemberContent +=
							" ActiveInSpace='" + Member.ActiveInSpace + "'" +
							" ActiveInTool='" + Member.ActiveInTool + "'" +
							" Awareness='" + Member.Awareness + "'" +
							" AwarenessState='" + Member.AwarenessState + "'" +
							" Role='" + Member.Role + "'" +
							" SyncState='" + Member.SyncState + "'" +
							" TimeWentIdle='" + Member.TimeWentIdle + "'";
					}

					OutputMemberContent += "/>";

					base.StandardOutput.WriteLine(OutputMemberContent);
				}
			}
		}
	
		
		private void WriteEndSpaceElement()
		{
			--m_StringPadCount;
			string SpaceStringPad = new string(' ', 2*m_StringPadCount);
			base.StandardOutput.WriteLine(SpaceStringPad + "</Space>");
		}
	}
}
